package sample;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import java.io.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Hello world!
 */
public class Main {

    @FXML
    private Button main_bu;

    @FXML
    void Cli_Main(ActionEvent event) {

    }

    static ObjectMapper objectMapper = new ObjectMapper();

    static File file;
    static String esIndexName;
    static String uri;
    static String user;
    static String pass;

    static {
        Properties properties = new Properties();
        InputStream resourceAsStream = Main.class.getClassLoader().getResourceAsStream("conf.properties");
        try {
            properties.load(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        file = new File(properties.getProperty("file"));
        esIndexName = properties.getProperty("esIndexName");
        uri = properties.getProperty("uri");
        user = properties.getProperty("user");
        pass = properties.getProperty("pass");
    }


    public static void main(String[] args) throws KeyManagementException, NoSuchAlgorithmException, IOException, BiffException {
        StringBuffer data = readAssemblydata(file);

//        System.out.println(data);
        writeOut(data);

        sendData(data.toString());
        System.out.println("Completed!");


    }


    public static void writeOut(StringBuffer content) throws IOException {
        String path = "C:\\Users\\Administrator\\Desktop\\out.txt";
        File file = new File(path);
        //如果文件不存在，则自动生成文件；
        if (!file.exists()) {
            file.createNewFile();
        }

        //引入输出流
        OutputStream outPutStream;
        try {
            outPutStream = new FileOutputStream(file);
            StringBuilder stringBuilder = new StringBuilder();//使用长度可变的字符串对象；
            stringBuilder.append(content);//追加文件内容
            //TODO 这里写你的代码逻辑;
            String context = stringBuilder.toString();//将可变字符串变为固定长度的字符串，方便下面的转码；
            byte[] bytes = context.getBytes("UTF-8");//因为中文可能会乱码，这里使用了转码，转成UTF-8；
            outPutStream.write(bytes);//开始写入内容到文件；
            outPutStream.close();//一定要关闭输出流；
        } catch (Exception e) {
            e.printStackTrace();//获取异常
        }
    }


    public static StringBuffer readAssemblydata(File excelPath) throws IOException, BiffException {
        ArrayList<Posts> posts = new ArrayList<>();
        List<String> subEntiyList = Arrays.asList(
                "安装经验", "数据加载及处理", "网络构建", "模型训练", "推理经验", "算子使用", "分布式并行", "调优经验",
                "应用实践", "基础知识", "特性分析", "论文解析", "前沿分享", "其它干货", "其他干货", "功能调试"
        );
        InputStream is = new FileInputStream(excelPath);

        System.out.println("Read data from local excel file, then assemble them simultaneously");
        jxl.Workbook rwb = Workbook.getWorkbook(is);
        Sheet rs = rwb.getSheet(0);
        int rowsCount = rs.getRows();
        try {
            int gostart = 0;
            for (int i = 0; i < rowsCount; i++) {
                //todo 分批次组装，防止oom
                Cell[] cell = rs.getRow(i);
                String datastr = cell[0].getContents();
                if (!StringUtils.isNotBlank(datastr)) {
                    System.out.println(String.format("第%s行已经为空, 请确认它是否为最后一行,数据行已遍历完.", i + 1));
                    break;
                }

                if ("发表时间".equals(datastr)) {
                    gostart = 1;
                    continue;
                }

                if (gostart == 0) {
                    continue;
                }
                Posts po = new Posts();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                Date parse = null;
                try {
                    parse = simpleDateFormat.parse(datastr);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String formatdate = simpleDateFormat2.format(parse);
                po.setCreated_at(parse);
                po.setTile(cell[1].getContents());
                po.setMoudle(cell[2].getContents());
                po.setAuthor(cell[4].getContents());
                String theme_category = cell[3].getContents();
                if (subEntiyList.contains(theme_category) || cell[3].getContents().equals("技术干货")) {      // There are many sub entities of 技术干货
                    po.setTheme("技术干货");
                }
                po.setReply_Num(cell[5].getContents());
                po.setBrowse_Num(cell[6].getContents());
                po.setLast_Update_time(cell[7].getContents());
                po.setUrl(cell[8].getContents());
                posts.add(po);
                if (po.getTile().contains("转载")) {
                    po.setIs_reprint(1);
                }
            }
        } catch (NullPointerException e) {
            System.out.println("please check excel!");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rwb.close();
            is.close();
        }


        StringBuffer resultBuffer = new StringBuffer();
        for (Posts post : posts) {
            String assemblydata = objectMapper.writeValueAsString(post);

            String indexstr = "{\"index\":{\"_index\":\"" + esIndexName + "\",\"_type\":\"_doc\",\"_id\":\"" +
                    post.getCreated_at() + "-" + post.getTile() + "-" + post.getAuthor() + "\"}}";
            resultBuffer.append(indexstr).append("\n").append(assemblydata).append("\n");
        }
        return resultBuffer;
    }


    public static ArrayList<JSONObject> getDataFromApi() throws Exception {
//        1. create connection object similar with requests in python

        ArrayList<JSONObject> result_json_list = new ArrayList<>();
        OkHttpClient client = new OkHttpClient().newBuilder().build();
        StringBuilder result_str = new StringBuilder();
        int max_page = 0;
        int current_page = 1;
        do {
            String data_url = String.format("https://bbs.huaweicloud.com/forum/api/rest/index.php?interface=get_forum_threads&fid=726&page=%d&orderby=dateline&limit=100", current_page);
            Response response = null;
            try {
                Request request = new Request.Builder().url(data_url)
                        .method("GET", null)
                        .addHeader("Cookie", "a3ps_1d41_lastvisit=1630399737; a3ps_1d41_saltkey=zUJTfOj7; HWWAFSESID=dd2f379422241a51b2; HWWAFSESTIME=1630403334992")
                        .build();
                response = client.newCall(request).execute();
            } catch (Exception e) {
                System.out.println("Failed to fetch the " + current_page + " page data because of some error during requesting.");
                System.out.println(e.getMessage());
                continue;
            }
            String each_text = response.body().source().readUtf8();
            result_str.append(each_text);
            JSONObject result_currentPage_json = JSONObject.parseObject(each_text);
            if (current_page == 1) {
                JSONObject first_json = JSONObject.parseObject(each_text);
                max_page = Integer.parseInt(first_json.getString("retMaxpage"));
            }
            result_json_list.add(result_currentPage_json);
            current_page += 1;
            // update data_url with current_page*******************************

        } while (current_page <= max_page);


//        2. send Request fetch data

        return result_json_list;
    }

    @Test
    public void methodTest() {
        try {
            ArrayList<JSONObject> dataFromApi = Main.getDataFromApi();
        } catch (Exception e) {
            e.printStackTrace();
        }


//        StringBuilder var = new StringBuilder("I am reus");
//        String s = String.valueOf(var);

        System.out.println("stop");


    }


    public static String sendData(String data) throws NoSuchAlgorithmException, KeyManagementException {
        System.out.println("Sending data to ElasticSearch...");
        CloseableHttpClient httpClient = HttpClientUtils.getClient();
        CloseableHttpResponse execute = null;
        data = data.replace("\\", "/");  // back slash can not be recognized by elasticsearch
        try {
            HttpPost httpPost = new HttpPost(uri + "/_bulk");
            httpPost.setEntity(new StringEntity(data, "UTF-8"));
            httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
            httpPost.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString((user + ":" + pass).getBytes()));
            execute = httpClient.execute(httpPost);
            return EntityUtils.toString(execute.getEntity());
        } catch (IOException e) {
            try {
                return EntityUtils.toString(execute.getEntity());


            } catch (IOException ioException) {
                return ioException.getMessage();

            }
        } finally {
            if (execute != null) {
                try {
                    EntityUtils.consume(execute.getEntity());
                } catch (IOException ignored) {

                }
            }
        }
    }

}
